import storageManager.Field;
import storageManager.FieldType;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;

/**
 * Created by IntelliJ IDEA.
 * User: mani
 * Date: 11/23/11
 * Time: 12:40 PM
 * To change this template use File | Settings | File Templates.
 */
public class Table {


    public ArrayList<MyTuple> tuples = new ArrayList<MyTuple>();
    public ArrayList<String> columnNames = new ArrayList<String>();


    public Table(ArrayList<String> columnNames) {
        this.columnNames = columnNames;
    }

    public Table() {

    }

    public void addColumnNames(String tableName, ArrayList<String> list) {
        for (String s : list) {
            columnNames.add(tableName + "." + s);
        }
    }

    public void add(ArrayList<MyTuple> addTuples) {
        tuples.addAll(addTuples);
    }

    public void add(MyTuple tuple) {
        tuples.add(tuple);
    }

    public void projectTable(final ArrayList<String> projColNames, boolean eliminateDuplicates, final String orderByColumn) {
        final ArrayList<MyTuple> temp_myTuples = new ArrayList<MyTuple>(tuples.size());


        final HashMap<String, Integer> newColumnIndexMap = new HashMap<String, Integer>();

        for (int i = 0; i < projColNames.size(); i++) {
            newColumnIndexMap.put(projColNames.get(i), i);
        }

        HashMap<String, String> duplicatesMap = new HashMap<String, String>();
        for (MyTuple t : tuples) {
            MyTuple temp_mytuple = new MyTuple(new ArrayList<Field>(projColNames.size()));

            for (int i = 0; i < columnNames.size(); i++) {
                Integer newIndex = newColumnIndexMap.get(columnNames.get(i));
                if (newIndex != null) {
                    Field f = t.values.get(i);
                    temp_mytuple.values.add(newIndex, f);
                }
            }

            if (!eliminateDuplicates || duplicatesMap.get(temp_mytuple.toString()) == null) {
                temp_myTuples.add(temp_mytuple);
                duplicatesMap.put(temp_mytuple.toString(), temp_mytuple.toString());
            }
        }

        if (orderByColumn != null) {

            Collections.sort(temp_myTuples, new Comparator<MyTuple>() {
                public int compare(MyTuple o1, MyTuple o2) {
                    Integer newIndex = newColumnIndexMap.get(orderByColumn);
                    if (newIndex != null) {
                        Field f1 = o1.values.get(newIndex);
                        Field f2 = o2.values.get(newIndex);

                        if (TinySQL.isNull(f1))
                            return -1;
                        else if (TinySQL.isNull(f2))
                            return 1;
                        else if (f1.type == FieldType.INT)
                            return f1.integer - f2.integer;
                        else if (f1.type == FieldType.STR20)
                            return f1.str.compareTo(f2.str);
                    }
                    return 0;
                }
            });
        }
        this.tuples = temp_myTuples;
        columnNames = projColNames;
    }

    public String toString() {
        StringBuilder b = new StringBuilder();
        for (String columnName : columnNames)
            b.append(columnName).append("\t");
        b.append("\n");

        for (MyTuple t : tuples)
            b.append(t.toString()).append("\n");

        return b.toString();
    }

    public static Table joinTables(Table table1, Table table2) {
        Table result = new Table();
        result.addColumnNames(table1.columnNames);
        result.addColumnNames(table2.columnNames);

        for (MyTuple table1_tuple : table1.tuples) {
            for (MyTuple table2_tuple : table2.tuples) {
                MyTuple t = new MyTuple(table1_tuple.values);
                t.addFields(table2_tuple.values);
                result.add(t);
            }
        }

        return result;
    }

    private void addColumnNames(ArrayList<String> c) {
        this.columnNames.addAll(c);
    }
}
